package com.si.service;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.si.entity.Login_Err_Log;
import com.si.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.si.dao.EntityDao;
import com.si.entity.SysUser;

import javax.servlet.http.HttpServletRequest;

@Service
public class SysUserService extends BaseService<SysUser> {

  @Autowired
  private EntityDao entityDao;

  @Autowired
  private Login_Err_LogService login_err_logService;


  private static int maxTime = 5; //连续5次后
  private static double hour = 1; //一小时内不可登录。

  /**
   * 通过用户名和密码查询
   *
   * @param userName
   * @param passWord
   * @return
   */
  @SuppressWarnings("unchecked")
  public Integer loginSysUser(String userName, String passWord, HttpServletRequest request) {
    SysUser sysUser = null;
    Map<String, Object> queryMap = new HashMap<String, Object>();
    queryMap.put("userName", userName);
    List<SysUser> list = (List<SysUser>) entityDao.createCriteria(SysUser.class, queryMap, null);
    if (list != null && list.size() > 0) {
      sysUser = list.get(0);
      if (null != sysUser) {    //如果登录id确实存在
        if (sysUser.getPassWord().equals(passWord)) { //并且密码输入正确
          if (this.checkWhenPwdOk(sysUser)) {    //校验该用户是否可以登录
            this.setErrZero(sysUser);    //如果可以确实的登录，则对表中错误登录次数置零
            //resultMap.put("user", user);
            request.getSession().setAttribute("session_sysUser", sysUser);
            request.getSession().setAttribute("session_sysUser_name", sysUser.getUserName());
            return 0;//成功
          } else {
            //resultMap.put("extMsg", "errMax");    //前台错误信息展现由上层代码实现。
            return 1;//失败锁定
          }
        } else {
          if (this.checkErrNum(sysUser)) {  //密码错误时的一系列操作
            //返回true时，错误次数超过了5次，需要返回特定的错误信息
            //resultMap.put("extMsg", "errMax");
            return 1;//锁定
          } else {
            //错误次数没有超过5次，返回一个空map，交由上层处理
            return 2;//登录失败
          }
        }
      }

    }
    return 2;//登录失败
  }


  private void setErrZero(SysUser user) {
    //将指定id的错误次数置零
    HashMap<String, Object> map = new HashMap<>();
    map.put("loguser", user.getId());
    List<Login_Err_Log> all = login_err_logService.getAll(map, null);
    for (Login_Err_Log log : all) {
      log.setNumber(0);
      login_err_logService.saveOrUpdate(log);
    }
    //client是操作数据库的方法，可以认为是SqlMapClientBuilder.buildSqlMapClient(Resources.getResourceAsReader("config/SqlMap.xml"));  这种东西。
    //this.client.update("login.err.updateForOk", user);
  }

  /**
   * 即使密码正确，也不能登录
   *
   * @param user
   * @return false 处于锁定中，无法登陆  true 可以正常登录
   */
  private boolean checkWhenPwdOk(SysUser user) {
    HashMap<String, Object> map = new HashMap<>();
    map.put("loguser", user.getId());
    List<Login_Err_Log> all = login_err_logService.getAll(map, null);
    if (all.size() == 0) {
      return true;    //err表中无数据，可以登录成功
    } else if (all.get(0).getNumber() >= maxTime) {
			Date date = new Date();
			Date d = all.get(0).getLast_date();
      Long endL = d.getTime();
      Long now = date.getTime();
      Long day = (now-endL) / 86400000;
      Long hour = ((now-endL) % 86400000) / 3600000;
      Long min = ((now-endL) % 86400000 % 3600000) / 60000;
      System.out.println(day+"天");
      System.out.println(hour+"小时");
      if (min>=30){
        all.get(0).setNumber(0);
        login_err_logService.saveOrUpdate(all.get(0));
      }
      System.out.println(min+"分钟");
      return false;
    } else {
      return true;
    }
  }

  //密码错误时的方法
  private boolean checkErrNum(SysUser user) {
    HashMap<String, Object> map = new HashMap<>();
    map.put("loguser", user.getId());
    List<Login_Err_Log> all = login_err_logService.getAll(map, null);
    Integer currentNumStr = null;
    if (all.size() == 0) {
      Login_Err_Log log = new Login_Err_Log();
      log.setNumber(0);
      log.setLast_date(new Date());
      log.setLoguser(user.getId());
      login_err_logService.save(log);
      //错误信息表与用户表并不是同步的，如果是新建的用户，err表中将没有对应数据，需要插入一条新数据
      //this.client.insert("login.err.insertUser", daoMap);
      //currentNumStr = "0";
      currentNumStr = 0;
    } else {
      map.put("loguser", user.getId());
      List<Login_Err_Log> all1 = login_err_logService.getAll(map, null);
      for (Login_Err_Log errLog : all1) {
        currentNumStr = errLog.getNumber();
      }
    }

    if (currentNumStr >= maxTime) {
      //若次数超过了，将不会修改登陆时间。那样做会导致一小时的校验错误
      Date date = new Date();
      Date d = all.get(0).getLast_date();
      Long endL = d.getTime();
      Long now = date.getTime();
      Long day = (now-endL) / 86400000;
      Long hour = ((now-endL) % 86400000) / 3600000;
      Long min = ((now-endL) % 86400000 % 3600000) / 60000;
      System.out.println(day+"天");
      System.out.println(hour+"小时");
      if (min>=30){
        all.get(0).setNumber(0);
        login_err_logService.saveOrUpdate(all.get(0));
      }
      System.out.println(min+"分钟");
      return true;
    }
    //执行+1或=1的操作
    map.put("loguser", user.getId());
    List<Login_Err_Log> all2 = login_err_logService.getAll(map, null);
    for (Login_Err_Log errLog : all2) {
      errLog.setNumber(errLog.getNumber() + 1);
      errLog.setLast_date(new Date());
      login_err_logService.saveOrUpdate(errLog);
    }

    return false;
  }
}
